case PHYSDEVOP_unmap_pirq:
case PHYSDEVOP_eoi:
case PHYSDEVOP_irq_status_query:
+ case PHYSDEVOP_get_free_pirq:
return do_physdev_op(cmd, arg);
default:
return -ENOSYS;
case PHYSDEVOP_unmap_pirq:
case PHYSDEVOP_eoi:
case PHYSDEVOP_irq_status_query:
+ case PHYSDEVOP_get_free_pirq:
return compat_physdev_op(cmd, arg);
break;
default:
old_irq = domain_pirq_to_irq(d, pirq);
old_pirq = domain_irq_to_pirq(d, irq);
- if ( (old_irq && (old_irq != irq) ) ||
+ if ( (old_irq > 0 && (old_irq != irq) ) ||
(old_pirq && (old_pirq != pirq)) )
{
dprintk(XENLOG_G_WARNING, "dom%d: pirq %d or irq %d already mapped\n",
}
irq = domain_pirq_to_irq(current->domain, map->index);
- if ( !irq )
+ if ( irq <= 0 )
{
if ( IS_PRIV(current->domain) )
irq = map->index;
setup_gsi.polarity);
break;
}
+ case PHYSDEVOP_get_free_pirq: {
+ struct physdev_get_free_pirq out;
+ struct domain *d;
+
+ d = rcu_lock_current_domain();
+
+ ret = -EFAULT;
+ if ( copy_from_guest(&out, arg, 1) != 0 )
+ break;
+
+ spin_lock(&d->event_lock);
+ out.pirq = get_free_pirq(d, out.type, 0);
+ d->arch.pirq_irq[out.pirq] = PIRQ_ALLOCATED;
+ spin_unlock(&d->event_lock);
+
+ ret = copy_to_guest(arg, &out, 1) ? -EFAULT : 0;
+
+ rcu_unlock_domain(d);
+ break;
+ }
default:
ret = -ENOSYS;
break;
#define physdev_manage_pci compat_physdev_manage_pci
#define physdev_manage_pci_t physdev_manage_pci_compat_t
+#define physdev_get_free_pirq compat_physdev_get_free_pirq
+#define physdev_get_free_pirq_t physdev_get_free_pirq_compat_t
+
#define COMPAT
#undef guest_handle_okay
#define guest_handle_okay compat_handle_okay
#define domain_pirq_to_irq(d, pirq) ((d)->arch.pirq_irq[pirq])
#define domain_irq_to_pirq(d, irq) ((d)->arch.irq_pirq[irq])
+#define PIRQ_ALLOCATED -1
#define domain_pirq_to_emuirq(d, pirq) ((d)->arch.pirq_emuirq[pirq])
#define domain_emuirq_to_pirq(d, emuirq) ((d)->arch.emuirq_pirq[emuirq])
#define IRQ_UNBOUND -1
typedef struct physdev_setup_gsi physdev_setup_gsi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
+/* leave PHYSDEVOP 22 free */
+
+/* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI
+ * the hypercall returns a free pirq */
+#define PHYSDEVOP_get_free_pirq 23
+struct physdev_get_free_pirq {
+ /* IN */
+ int type;
+ /* OUT */
+ uint32_t pirq;
+};
+
+typedef struct physdev_get_free_pirq physdev_get_free_pirq_t;
+DEFINE_XEN_GUEST_HANDLE(physdev_get_free_pirq_t);
+
/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **